#
#  Views.py
#  TurnShip
#
#  Created by Pete Lord on 22/12/2008.
#  Copyright (c) 2008 __MyCompanyName__. All rights reserved.
#
import pygame, Options, os, Interfaces

class GameView():
    def __init__(self, fullscreen, graphics):
        flags = (pygame.FULLSCREEN * fullscreen) | pygame.DOUBLEBUF | pygame.HWSURFACE # comment out the last one for epic software
        self.screen = pygame.display.set_mode((Options.SCREEN_WIDTH, Options.SCREEN_HEIGHT), flags)
        self.rect = pygame.Rect(0, 0, Options.SCREEN_WIDTH, Options.SCREEN_HEIGHT)
        self.rotation = 0 # facing north for northgasm. Implementation later for rotation of view. Yummy
        
        self.selected_counter = 0
        self.selected_counter_max = 20
        
        self.target_graphic = graphics[os.path.join("Data", "Tiles", "Target")]
        self.path_graphic = graphics[os.path.join("Data", "Tiles", "MovePath")]
        
        self.destinations = []

    def update(self):
        self.screen.fill((0, 0, 0))
        
        try:
            self.rect.center = self.destinations.pop(0)
        except IndexError:
            pass
        # Draw map
        self.entities.map.draw()
        
        # Draw selected path
        # If we have a ship selected
        if self.entities.selected:
            # If the player is drawing a path
            try:
                for tile in self.entities.selected.path:
                    self.draw((self.path_graphic[Options.ZOOM_LEVEL], pygame.Rect(shadow_location(self.entities, tile), self.path_graphic[Options.ZOOM_LEVEL].get_size())))
            except AttributeError:
                pass
        
        # Draw the current weapon's targets
        try:
            for direction in self.entities.targets:
                for x, y in direction:
                    target = self.entities.selected.get_tile_direction_relative(x, y, 0)
                    self.draw((self.target_graphic[Options.ZOOM_LEVEL], pygame.Rect(shadow_location(self.entities, target), self.target_graphic[Options.ZOOM_LEVEL].get_size())))
        except AttributeError:
            pass
            


        
        # Draw all entities   . -- - - -- - - - -- > INCLUDING SHIPS
        for entitity in self.entities.all():
            self.draw(entitity.draw())
            
        for effect in self.entities.effects.lower:
            self.draw(effect.draw())                

            
        # Draw night overlay
        self.entities.night_surface.set_alpha(self.entities.night)
        self.screen.blit(self.entities.night_surface, (0,0))
        
        # draw in ship lights
        if self.entities.night > 85:
            for player in self.entities.players.values():
                for ship in player.ships.values():
                    # we're doing lights this time, second subscript == 1
                    self.draw(ship.draw_lights())
                    

                
        # If we have selected a ship
        if self.entities.selected and not self.selected_counter / self.selected_counter_max:
            # If this is our ship
            if self.entities.selected in self.entities.player.ships.values():
                # Highlight in white
                colour = (255, 255, 255)
            # Otherwise, it's an enemy
            else:
                # Highlight in red
                colour = (255, 0, 0)
            surface, position = self.entities.selected.draw()
            # Create a copy of it's sprite
            mask = surface.copy()
            # Create a white mask of the non-transparent areas
            mask.fill(colour, None, pygame.BLEND_ADD)
            # Lower the alpha levels
            mask.fill(colour + (Options.HIGHLIGHT_ALPHA,), None, pygame.BLEND_RGBA_MULT)
            #mask.set_alpha(Options.HIGHLIGHT_ALPHA)
            # Blit the highlight to screen
            self.draw((mask, position))
            
        for effect in self.entities.effects.higher:
            self.draw(effect.draw())
        
        self.selected_counter = (self.selected_counter + 1) % (self.selected_counter_max * 2)
        
        # Draw interfaces
        for widget in self.entities.interface:
            if widget.absolute:
                self.draw(widget.draw())
            else:
                surface, position = widget.draw()
                left, top = position.topleft
                if left < 0:
                    left += self.rect.width - position.width
                if top < 0:
                    top += self.rect.height - position.height
                self.screen.blit(surface, (left, top))
            

    def draw(self, (surface, position)):
        # If the sprite is on screen
        if position.colliderect(self.rect):
            self.screen.blit(surface, position.move(-self.rect.x, -self.rect.y))

    def pan_by(self, x_amount, y_amount):
        self.rect.move_ip(x_amount, y_amount)
        
    def pan_to(self, x, y, time):
        # here for planning purposes
        # pan to an xy over time.
        x_dif = x - self.rect.centerx + Options.TILE_WIDTH[Options.ZOOM_LEVEL] / 2
        y_dif = y - self.rect.centery + Options.TILE_HEIGHT[Options.ZOOM_LEVEL] / 2
        print x_dif / time, y_dif / time
        #for i, j in zip(range(x_dif / time), range(y_dif / time)):
            #self.destinations.append((i * time, j * time))
        for i in range(time):
            self.destinations.append((self.rect.centerx + (i * x_dif / time), self.rect.centery + (i * y_dif / time)))
        
    def pan_to_tile(self, x, y, time):
        # here for planning purposes
        # pan to a tile over time
        pass
        
    def pan_to_ship(self, ship, time):
        # here for planning purposes 
        # pan to a ship over time. reads from the players own ships.
        x, y = ship.shadow_location()
        self.pan_to(x, y, time)

    def zoom(self, level):
        # Get the current distance of rect from (0, 0)
        centre_x, centre_y = self.rect.center
        # Account for the current zoom level
        centre_x, centre_y = centre_x * (2 ** Options.ZOOM_LEVEL), centre_y * (2 ** Options.ZOOM_LEVEL)
        # Set the new zoom level
        Options.ZOOM_LEVEL += level
        if Options.ZOOM_LEVEL < 0:
            Options.ZOOM_LEVEL = 0
        if Options.ZOOM_LEVEL > 2:
            Options.ZOOM_LEVEL = 2
        # Set the new view centre based on new zoom level
        self.rect.center = centre_x / (2 ** Options.ZOOM_LEVEL), centre_y / (2 ** Options.ZOOM_LEVEL)
        
    def toggle_fullscreen(self):
        flags = self.screen.get_flags() ^ pygame.FULLSCREEN
        if flags & pygame.FULLSCREEN == pygame.FULLSCREEN:
            size = pygame.display.list_modes()[0]
            self.rect.w = size[0]
            self.rect.h = size[1]
            resized = "Fullscreen "
        else:
            size = (Options.SCREEN_WIDTH, Options.SCREEN_HEIGHT)
            self.rect.w = Options.SCREEN_WIDTH
            self.rect.h = Options.SCREEN_HEIGHT
            resized = "Windowed "
        # reinitialise 'screen' surface
        self.screen = pygame.display.set_mode(size, flags)
        resized += str(self.screen.get_size())
        self.entities.interface.append(Interfaces.TimedBox(self.entities.interface, resized))

def shadow_location(entities, (x, y)):
    return (x - y + entities.map.height - 1) * 0.5 * Options.TILE_WIDTH[Options.ZOOM_LEVEL], (x + y) * 0.5 * Options.TILE_HEIGHT[Options.ZOOM_LEVEL]
